import React, { useCallback, useEffect, useState } from 'react';
import {
  Badge,
  Button,
  Card, Drawer, Form, Grid, Input,
  Notification,
  PaginationProps,
  Select,
  Space,
  Table
} from '@arco-design/web-react';
import { IconPlus, IconRefresh, IconSearch } from '@arco-design/web-react/icon';
import useLocale from '@/utils/useLocale';
import instance from '@/utils/request';
import { defaultDrawerLayout, defaultDrawerWidth, defaultPaginationProps } from '@/constants/defaults';
import { EditMode } from '@/constants/enums';
import { EnabledOptions } from '@/constants/options';
import { resolveEnabledName } from '@/constants/functions';
import { DictRequest, DictResponse } from '@/constants/type';
import { TableOperationButtonGroup } from '@/components/common/table_operation_button_group';

const { Row } = Grid;
const locale = {
  'en-US': {},
  'zh-CN': {
    'label.id': 'ID',
    'label.name': '字典名称',
    'label.code': '字典编码',
    'label.value': '字典值',
    'label.type': '字典类型',
    'label.parentId': '父级字典id',
    'label.remark': '字典备注',
    'label.enabled': '状态',
    'label.operations': '操作',

    'placeholder.id': '请输入字典ID',
    'placeholder.name': '请输入字典名称',
    'placeholder.code': '请输入字典编码',
    'placeholder.value': '请输入字典值',
    'placeholder.type': '请选择字典类型',
    'placeholder.parentId': '请选择父级id',
    'placeholder.remark': '请输入备注',
    'placeholder.enabled': '请选择字典状态',

    'title.create': '创建字典',
    'title.update': '修改字典',

    'columns.id': 'ID',
    'columns.name': '字典名称',
    'columns.code': '字典编码',
    'columns.value': '字典值',
    'columns.type': '字典类型',
    'columns.parentId': '父级字典id',
    'columns.remark': '字典备注',
    'columns.enabled': '状态',
    'columns.operations': '操作',

    'button.create': '创建',
    'button.update': '编辑',
    'button.delete': '删除',
    'button.search': '搜索',
    'button.reset': '重置'
  }
};

const SearchForm = (props: {
  onSubmit: ({}) => void,
  onReset: () => void,
}) => {
  const t = useLocale(locale);
  const [form] = Form.useForm();
  const [typeOptions, setTypeOptions] = useState([]);

  useEffect(() => {
    const fetchDictType = () => {
      instance
        .post('/api/dict/type', {})
        .then((res) => {
          if (res.data.code === 200) {
            setTypeOptions(res.data.data);
          }
        });
    };
    fetchDictType();
  }, []);

  return (
    <Form form={form} style={{ padding: '1rem', background: 'white' }}>
      <Row style={{ display: 'flex' }}>
        <Grid style={{ flexGrow: '1' }} cols={4} colGap={12} rowGap={16}>
          <Grid.GridItem>
            <Form.Item noStyle label={t['label.id']} field="id">
              <Input placeholder={t['placeholder.id']} allowClear />
            </Form.Item>
          </Grid.GridItem>
          <Grid.GridItem>
            <Form.Item noStyle label={t['label.name']} field="name">
              <Input allowClear placeholder={t['placeholder.name']} />
            </Form.Item>
          </Grid.GridItem>
          <Grid.GridItem>
            <Form.Item noStyle label={t['label.remark']} field="remark">
              <Input allowClear placeholder={t['placeholder.remark']} />
            </Form.Item>
          </Grid.GridItem>
          <Grid.GridItem>
            <Form.Item noStyle label={t['label.type']} field="type">
              <Select
                placeholder={t['placeholder.type']}
                options={typeOptions}
                allowClear
              />
            </Form.Item>
          </Grid.GridItem>
          <Grid.GridItem>
            <Form.Item noStyle label={t['label.enabled']} field="enabled">
              <Select
                placeholder={t['placeholder.enabled']}
                options={EnabledOptions}
                allowClear
              />
            </Form.Item>
          </Grid.GridItem>
        </Grid>
        <Row style={{ display: 'inline-flex', marginLeft: '1rem' }} justify={'center'}>
          <Space direction={'vertical'}>
            <Button type="primary" icon={<IconSearch />} onClick={() => props.onSubmit(form.getFieldsValue())}>
              {t['button.search']}
            </Button>
            <Button icon={<IconRefresh />} onClick={() => {
              form.resetFields();
              props.onReset();
            }}>
              {t['button.reset']}
            </Button>
          </Space>
        </Row>
      </Row>
    </Form>
  );
}, DictDrawer =
  (props: {
    record?: DictResponse
    visible: boolean;
    toggleVisible: (visible: boolean) => void;
    mode: EditMode;
    onFinish: () => void;
  }) => {
    const t = useLocale(locale);
    const [form] = Form.useForm<DictRequest>();
    const [confirmLoading, setConfirmLoading] = useState(false);
    const [parentIdOptions, setParentIdOptions] = useState([]);
    const [typeOptions, setTypeOptions] = useState([]);
    const title = () => {
      switch (props.mode) {
        case EditMode.Create:
          return t['title.create'];
        case EditMode.Update:
          return t['title.update'];
        default:
          return '';
      }
    };

    useEffect(() => {
      const fetchDictType = () => {
        instance
          .post('/api/dict/type', {})
          .then((res) => {
            if (res.data.code === 200) {
              setTypeOptions(res.data.data);
            }
          });
      };
      fetchDictType();
    }, []);

    function onSubmitDrawer() {
      form.validate().then(() => {
        setConfirmLoading(true);
        instance
          .post(props.mode === EditMode.Create ? '/api/dict/create' : '/api/dict/update', form.getFields())
          .then((res) => {
            if (res.data.code === 200) {
              // 刷新页面数据
              Notification.success({
                title: res.data.message,
                content: ''
              });
              setTimeout(props.onFinish, 100);
            } else {
              Notification.error({
                title: res.data.message,
                content: res.data.data
              });
            }
          })
          .finally(() => {
            form.resetFields();
            setConfirmLoading(false);
            props.toggleVisible(false);
          });
      });
    }

    useEffect(() => {
      form.resetFields();
      switch (props.mode) {
        case EditMode.Update:
          // 如果是更新模式，根据parentId查询父节点的信息
          if (!!props.record?.parentId) {
            instance
              .post('/api/dict/get', { id: props.record.parentId })
              .then((res) => {
                if (res.data.code === 200) {
                  setParentIdOptions([{
                    label: res.data.data.name,
                    value: res.data.data.id
                  }]);
                  form.setFieldValue('parentId', props.record?.parentId || null);
                } else {
                  setParentIdOptions(['未知']);
                }
              });
          }
          form.setFieldsValue(props.record);
          form.setFieldValue('enabled', props.record?.enabled + '' || 'false');
          break;
        case EditMode.Create:
          // 如果是创建模式，record则作为父节点的信息
          if (!!props.record?.name && !!props.record?.id) {
            setParentIdOptions([{
              label: props.record.name,
              value: props.record.id
            }]);
            form.setFieldValue('parentId', props.record?.id || null);
          }
          form.setFieldValue('enabled', 'true');
          form.setFieldValue('type', 'COMMON');
          break;
      }
    }, [props.record, props.mode]);

    return (
      <Drawer
        width={defaultDrawerWidth}
        title={<span>{title()}</span>}
        visible={props.visible}
        confirmLoading={confirmLoading}
        onOk={onSubmitDrawer}
        onCancel={() => props.toggleVisible(false)}
      >
        <Form {...defaultDrawerLayout} form={form} layout="vertical">
          <Form.Item label={t['label.name']} required field="name" rules={[{ required: true }]}>
            <Input placeholder={t['placeholder.name']} />
          </Form.Item>
          <Form.Item label={t['label.code']} required field="code" rules={[{ required: true }]}>
            <Input placeholder={t['placeholder.code']} />
          </Form.Item>
          <Form.Item label={t['label.value']} required field="value" rules={[{ required: true }]}>
            <Input placeholder={t['placeholder.value']} />
          </Form.Item>
          <Form.Item label={t['label.type']} field="type" rules={[{ required: true }]}>
            <Select placeholder={t['placeholder.type']} options={typeOptions} />
          </Form.Item>
          <Form.Item label={t['label.enabled']} field="enabled" rules={[{ required: false }]}>
            <Select placeholder={t['placeholder.enabled']} options={EnabledOptions} />
          </Form.Item>
          <Form.Item label={t['label.parentId']} field="parentId" rules={[{ required: false }]}>
            <Select placeholder={t['placeholder.parentId']} disabled options={parentIdOptions} />
          </Form.Item>
          <Form.Item label={t['label.remark']} field="remark" rules={[{ required: false }]}>
            <Input.TextArea placeholder={t['placeholder.remark']} />
          </Form.Item>
        </Form>
      </Drawer>
    );
  }, DictPage = () => {
  const t = useLocale(locale);
  const [data, setData] = useState([]);
  const [pagination, setPagination] = useState<PaginationProps>(defaultPaginationProps);
  const [loading, setLoading] = useState(true);
  const [formParams, setFormParams] = useState({});
  const [visible, setVisible] = useState(false);
  const [editMode, setEditMode] = useState(EditMode.Create);
  const [selectRecord, setSelectRecord] = useState<DictResponse>();
  const [typeOptions, setTypeOptions] = useState([]);
  const resolveDictType = useCallback((value) => {
    return (typeOptions || []).find(it => it.value === value).label || '';
  }, [typeOptions]);

  useEffect(() => {
    fetchDictType();
    fetchData();
  }, [pagination.current, pagination.pageSize, formParams]);

  const fetchDictType = () => {
    instance
      .post('/api/dict/type', {})
      .then((res) => {
        if (res.data.code === 200) {
          setTypeOptions(res.data.data);
        }
      });
  };

  function fetchData() {
    const { current, pageSize } = pagination;
    setLoading(true);
    instance
      .post('/api/dict/page', {
        pager: {
          pageNumber: current,
          pageSize
        },
        query: {
          ...formParams
        }
      })
      .then((res) => {
        setData(res.data.data);
        setPagination({
          ...pagination,
          current,
          pageSize,
          total: res.data.total
        });
        setLoading(false);
      });
  }

  function onDeleteRecord(id: number) {
    setLoading(true);
    instance
      .post('/api/dict/delete', { id: id })
      .then((res) => {
        if (res.data.code === 200) {
          Notification.success({
            title: res.data.message,
            content: ''
          });
        } else {
          Notification.error({
            title: res.data.message,
            content: res.data.data
          });
        }
      })
      .finally(() => {
        setLoading(false);
        setTimeout(fetchData, 100);
      });
  }

  function onCreateRecord(record: DictResponse) {
    setSelectRecord(record);
    setEditMode(EditMode.Create);
    setVisible(true);
  }

  function onUpdateRecord(record: DictResponse) {
    setSelectRecord(record);
    setEditMode(EditMode.Update);
    setVisible(true);
  }

  return (
    <Card>
      <SearchForm onSubmit={it => setFormParams(it)} onReset={() => setFormParams({})} />
      <Row justify={'space-between'}>
        <Space>
          <Button type="primary" icon={<IconPlus />} onClick={() => onCreateRecord(null)}>
            {t['button.create']}
          </Button>
        </Space>
      </Row>
      <Table style={{ marginTop: '1rem' }}
             rowKey={record => record.id}
             loading={loading}
             pagination={pagination}
             onChange={({ current, pageSize }) => setPagination({ ...pagination, current, pageSize })}
             columns={[
               {
                 title: t['columns.id'],
                 dataIndex: 'id'
               },
               {
                 title: t['columns.name'],
                 dataIndex: 'name'
               },
               {
                 title: t['columns.code'],
                 dataIndex: 'code'
               },
               {
                 title: t['columns.value'],
                 dataIndex: 'value'
               },
               {
                 title: t['columns.type'],
                 dataIndex: 'type',
                 render: (value: string) => resolveDictType(value)
               },
               {
                 title: t['columns.enabled'],
                 dataIndex: 'enabled',
                 render: (value: boolean) => {
                   return value === true
                     ? <Badge status="success" text={resolveEnabledName(value)}></Badge>
                     : <Badge status="error" text={resolveEnabledName(value)}></Badge>;
                 }
               },
               {
                 title: t['columns.remark'],
                 dataIndex: 'remark'
               },
               {
                 title: t['columns.operations'],
                 headerCellStyle: { paddingLeft: '15px' },
                 render: (_, record: DictResponse) => {
                   return <TableOperationButtonGroup
                     record={record}
                     onCreate={() => onCreateRecord(record)}
                     onUpdate={() => onUpdateRecord(record)}
                     onDelete={() => onDeleteRecord(record?.id)}
                   />;
                 }
               }
             ]}
             data={data} />
      <DictDrawer visible={visible} toggleVisible={setVisible}
                  mode={editMode} record={selectRecord} onFinish={fetchData} />
    </Card>
  );
};


export default DictPage;